﻿#region License
/*

	Copyright (C) 2008 Oliver Charles, Daniel Hollander

	This program is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with this program.  If not, see <http://www.gnu.org/licenses/>.
	
*/
#endregion

using System.Collections;
using System.Collections.Generic;
using Moebius.Core;

namespace Moebius.Controllers
{
    /// <summary>
    /// Manages a set of <see cref="Controller"/>s
    /// </summary>
    public class ControllerCollection : Task, ICollection<Controller>
    {
        private readonly List<Controller> controllers = new List<Controller>();

        #region Kernel Task Implementation

        /// <summary>
        /// Execute the <see cref="ControllerCollection"/> by executing all
        /// active <see cref="Controller"/>s
        /// </summary>
        /// <param name="elapsedTime"></param>
        public override void Execute(double elapsedTime)
        {
            controllers.ForEach(delegate(Controller controller)
                                    {
                                        if(controller.Active)
                                            controller.Update(elapsedTime);
                                    });
        }

        #endregion
        #region ICollection Implementation

        /// <summary>
        /// Add a <see cref="Controller"/> to be managed.
        /// </summary>
        /// <param name="item">The <see cref="Controller"/> to manage.</param>
        public void Add(Controller item)
        {
            if(!controllers.Contains(item))
                controllers.Add(item);
        }

        ///<summary>
        ///Removes all items from the <see cref="T:System.Collections.Generic.ICollection`1" />.
        ///</summary>
        ///
        ///<exception cref="T:System.NotSupportedException">The <see cref="T:System.Collections.Generic.ICollection`1" /> is read-only. </exception>
        public void Clear()
        {
            controllers.Clear();
        }

        ///<summary>
        ///Determines whether the <see cref="T:System.Collections.Generic.ICollection`1" /> contains a specific value.
        ///</summary>
        ///
        ///<returns>
        ///true if <paramref name="item" /> is found in the <see cref="T:System.Collections.Generic.ICollection`1" />; otherwise, false.
        ///</returns>
        ///
        ///<param name="item">The object to locate in the <see cref="T:System.Collections.Generic.ICollection`1" />.</param>
        public bool Contains(Controller item)
        {
            return controllers.Contains(item);
        }

        ///<summary>
        ///Copies the elements of the <see cref="T:System.Collections.Generic.ICollection`1" /> to an
        /// <see cref="T:System.Array" />, starting at a particular <see cref="T:System.Array" />
        /// index.
        ///</summary>
        ///
        ///<param name="array">The one-dimensional <see cref="T:System.Array" /> that is the destination of the elements copied from <see cref="T:System.Collections.Generic.ICollection`1" />. The <see cref="T:System.Array" /> must have zero-based indexing.</param>
        ///<param name="arrayIndex">The zero-based index in <paramref name="array" /> at which copying begins.</param>
        ///<exception cref="T:System.ArgumentNullException"><paramref name="array" /> is null.</exception>
        ///<exception cref="T:System.ArgumentOutOfRangeException"><paramref name="arrayIndex" /> is less than 0.</exception>
        public void CopyTo(Controller[] array, int arrayIndex)
        {
            controllers.CopyTo(array, arrayIndex);
        }

        /// <summary>
        /// Remove a <see cref="Controller"/> from management.
        /// </summary>
        /// <param name="item">The <see cref="Controller"/> to remove</param>
        public bool Remove(Controller item)
        {
            return controllers.Remove(item);
        }

        ///<summary>
        ///Gets the number of elements contained in the <see cref="T:System.Collections.Generic.ICollection`1" />.
        ///</summary>
        ///
        ///<returns>
        ///The number of elements contained in the <see cref="T:System.Collections.Generic.ICollection`1" />.
        ///</returns>
        ///
        public int Count
        {
            get { return controllers.Count; }
        }

        ///<summary>
        ///Gets a value indicating whether the <see cref="T:System.Collections.Generic.ICollection`1" /> is read-only.
        ///</summary>
        ///
        ///<returns>
        ///true if the <see cref="T:System.Collections.Generic.ICollection`1" /> is read-only; otherwise, false.
        ///</returns>
        ///
        public bool IsReadOnly
        {
            get { return false; }
        }

        ///<summary>
        ///Returns an enumerator that iterates through the collection.
        ///</summary>
        ///
        ///<returns>
        ///A <see cref="T:System.Collections.Generic.IEnumerator`1" /> that can be used to iterate through the collection.
        ///</returns>
        ///<filterpriority>1</filterpriority>
        IEnumerator<Controller> IEnumerable<Controller>.GetEnumerator()
        {
            return controllers.GetEnumerator();
        }

        ///<summary>
        ///Returns an enumerator that iterates through a collection.
        ///</summary>
        ///
        ///<returns>
        ///An <see cref="T:System.Collections.IEnumerator" /> object that can be used to iterate through the collection.
        ///</returns>
        ///<filterpriority>2</filterpriority>
        public IEnumerator GetEnumerator()
        {
            return ((IEnumerable<Controller>) this).GetEnumerator();
        }

        #endregion
    }
}